|
|
|
|
|
|
|
Windows内核调试
帖子发起人: mxzy55560593 发起时间: 2011-06-20 23:48 下午 回复: 6
|
帖子排序:
|
|
|
|
2011-06-20, 23:48 下午
|
mxzy55560593
注册: 2010-07-10
发 贴: 10
|
问个问题,有兴趣的朋友可以帮忙看看啦
|
|
|
|
对x86CPU的一个4字节变量赋值是不是原子操作?比如一个线程赋值0x12345678,另一个线程赋值0x87654321,会不会出现其他线程读取这个变量的值不是这两个值中的一个? 也就是需不需要加锁的问题
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2011-06-21, 13:50 下午
|
格蠹老雷
注册: 2005-12-19
发 贴: 1,303
|
|
|
如果是整型变量,编译器编译成一条MOV指令,那么执行这个MOV指令时一定是“原子”方式的
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2011-06-22, 11:42 上午
|
wrong
注册: 2011-01-07
发 贴: 66
|
|
|
这个问题是比较热门的问题。
一般的理解是不是的。
多处理器,多核情况下,多个线程可能读写同一个变量,要加锁。
该加volatile的,加 volatile。
该用InterLocked,就用InterLocked。
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2011-06-26, 13:03 下午
|
johnl
注册: 2008-09-29
发 贴: 9
|
|
|
取决于地址是否 4byte aligned, aligned 的是atomic, 可以不加锁。
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2011-06-26, 16:37 下午
|
格蠹老雷
注册: 2005-12-19
发 贴: 1,303
|
|
|
多谢补充,不过,今天的编译器都会自动把四字节的整型变量按DWORD对齐的,除非定义结构时特别用pragma声明
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2011-06-30, 09:48 上午
|
wrong
注册: 2011-01-07
发 贴: 66
|
|
|
找到一个帖子,希望有帮助。
http://user.qzone.qq.com/31731705/blog/1309358011
在单CPU系统中,能够在单条指令中完成的操作都是"原子操作",因为中断只能发生于指令之间。
但是,在多CPU结构中就不同了,由于系统中有多个CPU在独立地运行,即使能在单条指令中完成的操作也有可能受到干扰。我们以decl (递减指令)为例,这是一个典型的"读-改-写"过程,涉及两次内存访问。设想在不同CPU运行的两个进程都在递减某个内存单元的数值2,可能发生的情况是:
1. CPU A从内存单元把当前数值2装载进它的寄存器中;
2. CPU B从内存单元把当前数值2装载进它的寄存器中。
3. CPU A在它的寄存器中将计数值递减为1;
4. CPU B在它的寄存器中将计数值递减为1;
5. CPU A把修改后的计数值1写回内存单元。
6. CPU B把修改后的计数值1写回内存单元。
我们看到,内存里的计数值应该是0,然而它却是1。
可见原子操作不可能由软件单独保证--必须需要硬件的支持,因此是和架构相关的。在x86 平台上,CPU提供了在指令执行期间对总线加锁的手段。CPU芯片上有一条引线#HLOCK pin,如果汇编语言的程序中在一条指令前面加上前缀"LOCK",经过汇编以后的机器代码就使CPU在执行这条指令的时候把#HLOCK pin的电位拉低,持续到这条指令结束时放开,从而把总线锁住,这样同一总线上别的CPU就暂时不能通过总线访问内存了,保证了这条指令在多处理器环境中的原子性---这正是Interlocked 系互锁函数的本质和真象。
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2011-06-30, 13:15 下午
|
skyworth
注册: 2008-06-07
发 贴: 55
|
|
|
呵呵,这个跟你说的东西是两个问题。
一个是操作中途被打断,另一个是操作被覆盖。
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
高端调试 » 软件调试 » Windows内核调试 » 问个问题,有兴趣的朋友可以帮忙看看啦
|
|
|
|
|
|